package com.atwisdom.star.core.dsl.modelClass.resource.Impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.common.vo.ModelType;
import com.atwisdom.star.common.vo.PageInfo;
import com.atwisdom.star.core.dao.pojo.modelClass.resource.ResourceInstance;
import com.atwisdom.star.core.dao.pojo.modelClass.resource.ResourceInstanceHistory;
import com.atwisdom.star.core.dao.pojo.modelClass.resource.ResourceModel;
import com.atwisdom.star.core.dao.service.modelClass.resource.ResourceInstanceHistoryService;
import com.atwisdom.star.core.dao.service.modelClass.resource.ResourceInstanceService;
import com.atwisdom.star.core.dao.service.modelClass.resource.ResourceModelService;
import com.atwisdom.star.core.dsl.cache.ModelCacheDslService;
import com.atwisdom.star.core.dsl.modelClass.resource.ResourceModelDslService;
import com.atwisdom.star.core.dsl.modelClass.utils.QueryBuilder;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class ResourceModelDslServiceImpl implements ResourceModelDslService {

    private ResourceModelService resourceModelService;
    private ResourceInstanceService resourceInstanceService;
    private ResourceInstanceHistoryService resourceInstanceHistoryService;

    private QueryBuilder queryBuilder;

    private ModelCacheDslService modelCacheDslService;

    @Autowired
    public void setModelCacheDslService(ModelCacheDslService modelCacheDslService) {
        this.modelCacheDslService = modelCacheDslService;
    }

    @Autowired
    public void setResourceModelService(ResourceModelService resourceModelService) {
        this.resourceModelService = resourceModelService;
    }

    @Autowired
    public void setResourceInstanceService(ResourceInstanceService resourceInstanceService) {
        this.resourceInstanceService = resourceInstanceService;
    }

    @Autowired
    public void setResourceInstanceHistoryService(ResourceInstanceHistoryService resourceInstanceHistoryService) {
        this.resourceInstanceHistoryService = resourceInstanceHistoryService;
    }

    @Autowired
    public void setQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }


    /**
     * 查询全部摘要（通用）
     * @return 返回搞要列表
     */
    @Override
    public List<JSONObject> queryAllInfo() {
        try {
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildInfoSelection(queryWrapper);
            List<ResourceModel> list = resourceModelService.list(queryWrapper);
            return this.getResourceModelJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "无条件查询所有模型信息！");
        }
    }

    /**
     * 分页查询全部摘要（通用）
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回全部搞要列表
     */
    @Override
    public PageInfo queryAllInfoByPage(int pageNumber, int pageSize, String orderBy) {
        try {
            Page<ResourceModel> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询摘要模型信息！",ex);
        }
    }

    /**
     * 查询全部数据（通用）
     *
     * @return 返回结果
     */
    @Override
    public List<JSONObject> queryAll() {
        try {
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildModelFields(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper,null,"className,updateTime");
            List<ResourceModel> list = resourceModelService.list();
            return this.getResourceModelJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "无条件查询所有模型信息！");
        }
    }

    /**
     * 分页无条件查询模型信息
     *
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回值
     */
    @Override
    public PageInfo listAllByPage(int pageNumber,int pageSize,String orderBy) {
        try {
            Page<ResourceModel> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("published",true);
            queryBuilder.buildModelFields(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }

    /**
     * 查询模型
     *
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> query(String condition,String className,String orderBy) {
        try{
            condition = queryBuilder.transformOperator(condition);
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq("published", true);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            List<ResourceModel> list = resourceModelService.list(queryWrapper);
            return this.getResourceModelJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "查询模型失败！",ex);
        }
    }

    /**
     * 按条件查询模型摘要
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
   public PageInfo queryInfoByPage(int pageNumber,int pageSize, String condition,String className,String orderBy){
       condition = queryBuilder.transformOperator(condition);
       Page<ResourceModel> pageInfo = new Page<>(pageNumber, pageSize);
       QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
       queryWrapper.eq(StringUtils.isNotBlank(className), "className", className);
       queryWrapper.eq("published", true);
       queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
       queryBuilder.buildInfoSelection(queryWrapper);
       queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
       return getPageInfoResult(pageInfo, queryWrapper);
    }

    /**
     * 按条件查询模型
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    public PageInfo queryByPage(int pageNumber,int pageSize, String condition,String className,String orderBy){
        condition = queryBuilder.transformOperator(condition);
        Page<ResourceModel> pageInfo = new Page<>(pageNumber, pageSize);
        QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(className), "className", className);
        queryWrapper.eq("published", true);
        queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
        queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
        return getPageInfoResult(pageInfo, queryWrapper);
    }


    /**
     * 分页无条件查询所有版本搞要信息
     *
     * @param pageNumber 参数
     * @param pageSize 参数
     * @param orderBy 参数
     * @return 返回值
     */
    @Override
    public PageInfo queryAllVersionInfoByPage(int pageNumber,int pageSize,String orderBy) {
        try {
            Page<ResourceModel> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }

    /**
     * 分页条件查询版本搞要信息
     *
     * @param pageNumber 查询参数
     * @param pageSize 查询参数
     * @param condition 查询参数
     * @param className 查询参数
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public PageInfo queryVersionInfoByPage(int pageNumber,int pageSize,String condition,String className,String orderBy) {
        try {
            condition = queryBuilder.transformOperator(condition);
            Page<ResourceModel> pageInfo = new Page<>(pageNumber, pageSize);
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className), "className", className);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildInfoSelection(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            return getPageInfoResult(pageInfo, queryWrapper);
        }catch (Exception ex){
            throw new BusinessException("999999", "分页无条件查询模型信息！");
        }
    }

    /**
     *按条件和版本查询（通用）
     * @param condition 查询参数
     * @param className 类名参数
     * @param version 版本
     * @param orderBy 排序参数
     * @return 返回值
     */
    @Override
    public List<JSONObject> queryVersion(String condition,String className,BigDecimal version,String orderBy) {
        try{
            condition = queryBuilder.transformOperator(condition);
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
            queryWrapper.eq(version!=null,"version", version);
            queryWrapper.apply(StringUtils.isNotBlank(condition), condition);
            queryBuilder.buildModelFields(queryWrapper);
            queryBuilder.buildOrderBy(queryWrapper, orderBy, "className,updateTime,id");
            List<ResourceModel> list = resourceModelService.list(queryWrapper);
            return this.getResourceModelJsonObjectList(list);
        }catch (Exception ex){
            throw new BusinessException("999999", "查询模型失败！",ex);
        }
    }

    /**
     * 模型发布
     *
     * @param className 接收类名
     * @param version 接收版本
     * @return 返回结果
     */
    @Override
    public int setPublish(String className, BigDecimal version) {
        if (StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "模型类名为空，版本升级失败！");
        }

        if (version == null) {
            throw new BusinessException("999999", "模型版本为空，版本升级失败！");
        }

        //更新发布的实例
        QueryWrapper<ResourceInstance> instanceWrapperPublished = new QueryWrapper<>();
        instanceWrapperPublished.eq("className", className);
        instanceWrapperPublished.eq("version", version);
        ResourceInstance resourceInstancePublished = new ResourceInstance();
        resourceInstancePublished.setPublished(true);
        resourceInstanceService.update(resourceInstancePublished, instanceWrapperPublished);

        //更新取消发布的实例
        QueryWrapper<ResourceInstance> instanceWrapperUnpublished = new QueryWrapper<>();
        instanceWrapperUnpublished.eq("className", className);
        instanceWrapperUnpublished.ne("version", version);
        ResourceInstance resourceInstanceUnpublished = new ResourceInstance();
        resourceInstanceUnpublished.setPublished(false);
        resourceInstanceService.update(resourceInstanceUnpublished, instanceWrapperUnpublished);

        //更新取消发布的模型
        ResourceModel resourceModelUnpublished = new ResourceModel();
        resourceModelUnpublished.setPublished(false);
        QueryWrapper<ResourceModel> queryWrapperUnpublished = new QueryWrapper<>();
        queryWrapperUnpublished.eq("className", className);
        queryWrapperUnpublished.ne("version", version);
        this.resourceModelService.update(resourceModelUnpublished, queryWrapperUnpublished);

        //更新发布模型
        QueryWrapper<ResourceModel> queryWrapperPublished = new QueryWrapper<>();
        queryWrapperPublished.eq("className",className);
        queryWrapperPublished.eq("version",version);
        ResourceModel resourceModelPublished = new ResourceModel();
        resourceModelPublished.setPublished(true);
        int publishedCount = this.resourceModelService.getBaseMapper().update(resourceModelPublished, queryWrapperPublished);
        this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), className);
        return publishedCount;
    }

    /**
     * 模型取消发布
     *
     * @param className 接收参数
     * @return 返回统一结果类型(ResultInfo)
     */
    @Override
    public int setUnPublish(String className) {
        if (StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "模型类名为空，取消发布失败！");
        }
        ResourceModel resourceModel = this.modelCacheDslService.queryModel(ModelType.Resource.getCode(), className);
        BigDecimal version = resourceModel.getVersion();

        //更新取消发布的实例
        QueryWrapper<ResourceInstance> instanceWrapperUnpublished = new QueryWrapper<>();
        instanceWrapperUnpublished.eq("className", className);
        instanceWrapperUnpublished.eq("version", version);
        ResourceInstance resourceInstanceUnpublished = new ResourceInstance();
        resourceInstanceUnpublished.setPublished(false);
        this.resourceInstanceService.update(resourceInstanceUnpublished, instanceWrapperUnpublished);

        //更新取消发布的实例历史
        QueryWrapper<ResourceInstanceHistory> instanceHistoryWrapperUnpublished = new QueryWrapper<>();
        instanceHistoryWrapperUnpublished.eq("className", className);
        instanceHistoryWrapperUnpublished.eq("version", version);
        ResourceInstanceHistory resourceInstanceHistoryUnpublished = new ResourceInstanceHistory();
        resourceInstanceHistoryUnpublished.setPublished(false);
        this.resourceInstanceHistoryService.update(resourceInstanceHistoryUnpublished, instanceHistoryWrapperUnpublished);


        //更新取消发布的模型
        ResourceModel resourceModelUnpublished = new ResourceModel();
        resourceModelUnpublished.setClassName(className);
        resourceModelUnpublished.setPublished(false);
        QueryWrapper<ResourceModel> queryWrapperUnpublished = new QueryWrapper<>();
        queryWrapperUnpublished.eq("className", className);
        queryWrapperUnpublished.eq("version", version);
        int unpublishedCount = this.resourceModelService.getBaseMapper().update(resourceModelUnpublished, queryWrapperUnpublished);
        this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), className);
        return unpublishedCount;
    }

    /**
     * 版本升级
     *
     * @param className 接收参数
     * @throws BusinessException 业务异常
     * @return 返回结果
     */
    @Override
    public int upgrade(String className) {
        if (StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "模型类名为空，版本升级失败！");
        }
        try {
            ResourceModel resourceModel = this.modelCacheDslService.queryModel(ModelType.Resource.getCode(), className);
            BigDecimal version = resourceModel.getVersion();
            this.setUnPublish(className);
            BigDecimal newVersion = queryBuilder.getNewVersion(version);
            resourceModel.setVersion(newVersion);
            resourceModel.setId(null);
            resourceModel.setPublished(true);
            int insertModelCount = this.resourceModelService.getBaseMapper().insert(resourceModel);
            this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), className);
            return insertModelCount;
        }catch(Exception ex){
            throw new BusinessException("999999", "版本升级失败！");
        }
    }

    /**
     * 添加模型
     *
     * @param type 参数
     * @param className 参数
     * @return 返回值
     */
    @Override
    public JSONObject add(String type, String className) {
        if (this.existModel(type, className,null,false)) {
            throw new BusinessException("999999", "模型已存在！");
        }
        try {
            ResourceModel resourceModel = new ResourceModel(type, className);
            this.resourceModelService.getBaseMapper().insert(resourceModel);
            return resourceModel.fetchJsonObject();
        } catch (Exception ex) {
            throw new BusinessException("999999", "添加模型失败！", ex);
        }
    }

    /**
     * 拷贝模型
     *
     * @param type 参数
     * @param className 参数
     * @param oldType 参数
     * @param oldClassName 参数
     * @return 返回值
     */
    @Override
    public JSONObject clone(String type, String className, String oldType, String oldClassName) {
        if(StringUtils.isBlank(type) || StringUtils.isBlank(className) || StringUtils.isBlank(oldType) || StringUtils.isBlank(oldClassName) ){
            throw new BusinessException("999999", "拷贝模型：type,className和原模型：oldType,oldClassName都不能为空！");
        }
        if (this.existModel(type, className,null,false)) {
            throw new BusinessException("999999", "模型已存在，复制模型失败！");
        }

        try {
            //同步实例
            ResourceModel resourceModel = this.modelCacheDslService.queryModel(ModelType.Resource.getCode(), oldClassName);
            resourceModel.setId(null);
            resourceModel.setClassName(className);
            resourceModel.setType(type);
            resourceModel.setVersion(new BigDecimal("1.0"));
            this.resourceModelService.getBaseMapper().insert(resourceModel);
            return resourceModel.fetchJsonObject();
        }catch (Exception ex){
            throw new BusinessException("999999", "模型拷贝失败！", ex);
        }
    }

    /**
     * 更新模型类型和类名（配置阶段）
     * @param type 要变更的类型
     * @param className  要变更的类名
     * @param oldType   原类型
     * @param oldClassName 原类名
     * @return 返回模型记录
     */
    public JSONObject updateClassName(String type, String className, String oldType, String oldClassName) {
        if (StringUtils.isBlank(type) || StringUtils.isBlank(className) || StringUtils.isBlank(oldType) || StringUtils.isBlank(oldClassName)) {
            throw new BusinessException("999999", "更新模型类型和类名：type,className和：oldType,oldClassName都不能为空！");
        }

        if (this.existModel(type, className, "1.0", true)) {
            throw new BusinessException("999999", "模型已存在，更新模型类型和类名失败！");
        }

        try {
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("className", oldClassName);
            queryWrapper.eq("type", oldType);
            queryWrapper.eq("published", true);
            ResourceModel resourceModel = this.resourceModelService.getOne(queryWrapper);
            resourceModel.setType(type);
            resourceModel.setClassName(className);
            this.resourceModelService.updateById(resourceModel);
            //同步实例
            this.resourceInstanceService.updateClassName(type, className, oldType, oldClassName);

            //同步历史
            this.resourceInstanceHistoryService.updateClassName(type, className, oldType, oldClassName);
            this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), oldClassName);

            return resourceModel.fetchJsonObject();
        } catch (Exception ex) {
            throw new BusinessException("999999", "更新模型类型和类名", ex);
        }
    }


    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param jsonObject 参数
     * @return 返回值
     */
    @Override
    public JSONObject updateById(JSONObject jsonObject) {
        try {
            ResourceModel resourceModel =new ResourceModel(jsonObject);
            resourceModelService.getBaseMapper().updateById(resourceModel);
            //同步实例
//            ResourceModel oldModel = this.modelCacheDslService.queryModel(ModelType.Resource.getCode(), resourceModel.getClassName());
            //同步更新实例
//            this.updateInstanceByModel(resourceModel, oldModel);
            //同步更新历史数据
//            this.updateInstanceHistoryByModel(resourceModel, oldModel);
            //删除缓存模型
            this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), resourceModel.getClassName());

            return resourceModel.fetchJsonObject();
        }catch (Exception ex){
            throw new BusinessException("999999", "更新模型属性字段失败！");
        }
    }

    /**
     * 按ids删除模型
     * @param ids id列表
     * @return 返回结果
     */
    public boolean deleteByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new BusinessException("999999", "ids列表不能为空，删除模型失败！");
        }
        //删除缓存
        try {
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids);
            queryWrapper.eq("published", true);
            List<ResourceModel> list = this.resourceModelService.list(queryWrapper);
            //删除模型
            this.resourceModelService.remove(queryWrapper);
            //删除实例
            list.forEach(l->{
                this.deleteModelInstanceByClassName(l.getClassName());
                //删除缓存
                this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), l.getClassName());
            });
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", "按ids删除模型失败！", ex);
        }
    }

    /**
     * 接className删除
     * 1、删除实例、2、删除历史 3、更新redis
     *
     * @param className 模型类名
     * @return 返回值
     */
    @Override
    public boolean deleteByClassName(String className) throws BusinessException {
        if (StringUtils.isBlank(className)) {
            throw new BusinessException("999999", "模型类名称不能为空,删除模型失败！");
        }
        //删除缓存
        try {
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("className", className);
            queryWrapper.eq("published", true);
            //删除模型
            this.resourceModelService.remove(queryWrapper);
            //删除实例
            this.deleteModelInstanceByClassName(className);
            //删除缓存
            this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), className);
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", String.format("删除模型%s失败!", className), ex);
        }
    }

    /**
     * 批量删除
     *
     * @param classNames 参数
     * @return 返回值
     */
    @Override
    public boolean deleteByClassNames(List<String> classNames) {
        if (classNames == null || classNames.size() < 1) {
            throw new BusinessException("999999", "模型类名称列表不能为空,删除模型失败！");
        }
        try {
            classNames.forEach(className -> {
                QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("className", className);
                queryWrapper.eq("published", true);
                try {
                    //删除模型
                    this.resourceModelService.getBaseMapper().delete(queryWrapper);
                    //删除模型实例和实例历史
                    this.deleteModelInstanceByClassName(className);
                    //删除缓存
                    this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), className);
                } catch (Exception ex) {
                    String errMsg = "删除模型(s%)失败!";
                    throw new BusinessException("999999", String.format(errMsg, className), ex);
                }
            });
            return true;
        }catch (Exception ex){
            throw new BusinessException("999999", "模型类名称列表删除模型失败！");
        }
    }

    /**
     * 按Id 废除模型
     * @param ids 参数
     * @return 返回结果
     */
    public boolean repealByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new BusinessException("999999", "ids列表不能为空，废除模型失败！");
        }
        //删除缓存
        try {
            QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", ids);
            queryWrapper.eq("published", true);
            List<ResourceModel> list = this.resourceModelService.list(queryWrapper);
            //废除模型
            list.forEach(l -> {
                l.setDeleteFlag(true);
                this.resourceModelService.updateById(l);
            });

            //删除实例
            list.forEach(l -> {
                this.repealModelInstanceByClassName(l.getClassName());
                //删除缓存
                this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), l.getClassName());
            });
            return true;
        } catch (Exception ex) {
            throw new BusinessException("999999", "按ids删除模型失败！", ex);
        }

    }

    /**
     * 批量废除
     *
     * @param classNames 参数
     * @return 返回值
     */
    @Override
    public boolean repealByClassNames(List<String> classNames) {
        if (classNames == null || classNames.size() < 1) {
            throw new BusinessException("999999", "模型类名称列表不能为空,删除模型失败！");
        }
        try {
            classNames.forEach(className -> {
                QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("className", className);
                queryWrapper.eq("published", true);
                try {
                    //删除模型
                    this.resourceModelService.getBaseMapper().delete(queryWrapper);
                    //删除模型实例和实例历史
                    this.repealModelInstanceByClassName(className);
                    //删除缓存
                    this.modelCacheDslService.deleteModel(ModelType.Resource.getCode(), className);
                } catch (Exception ex) {
                    String errMsg = "删除模型(s%)失败!";
                    throw new BusinessException("999999", String.format(errMsg, className), ex);
                }
            });
            return true;
        }catch (Exception ex){
            throw new BusinessException("999999", "模型类名称列表删除模型失败！");
        }
    }


    /**
     * 根据模型更新实例数据
     *
     * @param newModel 新模型参数
     * @param oldModel 老的模型参数
     */
    private void updateInstanceByModel(ResourceModel newModel, ResourceModel oldModel) {
        QueryWrapper<ResourceInstance> instanceQueryWrapper = new QueryWrapper<>();
        instanceQueryWrapper.eq("className", newModel.getClassName());
        instanceQueryWrapper.eq("published", true);
        List<ResourceInstance> instanceList = this.resourceInstanceService.list(instanceQueryWrapper);
        List<ResourceInstance> updateInstanceList = dealInstanceList(newModel, oldModel, instanceList, ResourceInstance.class);
        this.resourceInstanceService.updateBatchById(updateInstanceList);
    }

    /**
     * 跟据模型更新实例历吏数据
     *
     * @param newModel 新模型
     * @param oldModel 旧模型
     */
    private void updateInstanceHistoryByModel(ResourceModel newModel, ResourceModel oldModel) {
        QueryWrapper<ResourceInstanceHistory> instanceQueryWrapper = new QueryWrapper<>();
        instanceQueryWrapper.eq("className", newModel.getClassName());
        instanceQueryWrapper.eq("published", true);
        List<ResourceInstanceHistory> instanceList = this.resourceInstanceHistoryService.list(instanceQueryWrapper);
        List<ResourceInstanceHistory> updateInstanceList = dealInstanceList(newModel, oldModel, instanceList, ResourceInstanceHistory.class);
        this.resourceInstanceHistoryService.updateBatchById(updateInstanceList);
    }

    /**
     * 处理实例列表
     *
     * @param newModel     新模型数据
     * @param oldModel     老的模型数据
     * @param instanceList 要同步的实例列表
     * @param clazz        要同步类类型
     * @param <T>          泛型参数
     * @return 返回结果
     */
    private <T> List<T> dealInstanceList(ResourceModel newModel, ResourceModel oldModel, List<T> instanceList, Class<T> clazz) {
        List<T> updateInstanceList = new ArrayList<>();
        instanceList.forEach(ins -> {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(ins));
            List<JSONObject> featureProperties = newModel.fetchFeatureProperties();
            List<JSONObject> oldFeatureProperties = oldModel.fetchFeatureProperties();
            featureProperties.forEach(fp -> {
                String code = fp.getString("code");
                String name = fp.getString("name");
                Object defaultValue = fp.get("defaultValue");
                Optional<JSONObject> first = oldFeatureProperties.stream().filter(m -> m.getString("code").equalsIgnoreCase(code) && m.getString("name").equalsIgnoreCase(name)).findFirst();
                Map<String, Object> oldFeature = first.orElse(null);
                if (oldFeature == null) {
                    jsonObject.put(code, defaultValue);
                }
            });

            oldFeatureProperties.forEach(fp -> {
                String code = fp.getString("code");
                Optional<JSONObject> first = featureProperties.stream().filter(m -> m.getString("code").equalsIgnoreCase(code)).findFirst();
                Map<String, Object> feature = first.orElse(null);
                if (feature == null) {
                    jsonObject.put(code, null);
                }
            });

            //非查询属性合并
            JSONObject insValues = (JSONObject) jsonObject.get("values");
            JSONObject nonValues = newModel.fetchNonFeatureValues();
            JSONObject values = JsonUtil.merge(nonValues, insValues);
            jsonObject.put("values", values);
            T instance = JSON.toJavaObject(jsonObject, clazz);
            updateInstanceList.add(instance);
        });
        return updateInstanceList;
    }

    /**
     * 按类名称删除实例和历史
     * @param className 类名
     */
    private void deleteModelInstanceByClassName(String className) {
        //删除实例
        QueryWrapper<ResourceInstance> instanceQueryWrapper = new QueryWrapper<>();
        instanceQueryWrapper.eq("className", className);
        instanceQueryWrapper.eq("published", true);
        this.resourceInstanceService.realDelete(instanceQueryWrapper);
        //删除历史
        QueryWrapper<ResourceInstanceHistory> instanceHistoryQueryWrapper = new QueryWrapper<>();
        instanceHistoryQueryWrapper.eq("className", className);
        instanceHistoryQueryWrapper.eq("published", true);
        this.resourceInstanceHistoryService.realDelete(instanceHistoryQueryWrapper);
    }

    /**
     * 按类名称废除实例和历史
     * @param className 类名
     */
    private void repealModelInstanceByClassName(String className) {
        //废除实例
        QueryWrapper<ResourceInstance> instanceQueryWrapper = new QueryWrapper<>();
        instanceQueryWrapper.eq("className", className);
        instanceQueryWrapper.eq("published", true);
        this.resourceInstanceService.remove(instanceQueryWrapper);
        //废除历史
        QueryWrapper<ResourceInstanceHistory> instanceHistoryQueryWrapper = new QueryWrapper<>();
        instanceHistoryQueryWrapper.eq("className", className);
        instanceHistoryQueryWrapper.eq("published", true);
        this.resourceInstanceHistoryService.remove(instanceHistoryQueryWrapper);
    }

    /**
     * 获取分页查询
     * @param pageInfo 分页信息
     * @param queryWrapper 查询wrapper
     * @return 返回结果
     */
    private PageInfo getPageInfoResult(Page<ResourceModel> pageInfo, QueryWrapper<ResourceModel> queryWrapper) {
        Page<ResourceModel> queryPage = resourceModelService.page(pageInfo, queryWrapper);
        List<ResourceModel> records = queryPage.getRecords();
        List<JSONObject> modelJsonObjectList = this.getResourceModelJsonObjectList(records);
        Page<JSONObject> queryPageDTO = new Page<>();
        BeanUtils.copyProperties(queryPage, queryPageDTO);
        queryPageDTO.setRecords(modelJsonObjectList);
        return PageInfo.of(queryPageDTO);
    }

    /**
     * 检查模型是否存在
     * @param type 类型
     * @param className 类名称
     * @return 返回是否存，true 存在，false 不存在
     */
    private boolean existModel(String type, String className,String version,boolean hasPublished) {
        QueryWrapper<ResourceModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(type),"type", type);
        queryWrapper.eq(StringUtils.isNotBlank(className),"className", className);
        if(StringUtils.isNotBlank(version)){
            queryWrapper.eq(StringUtils.isNotBlank(version),"version",version);
        }
        queryWrapper.eq(hasPublished,"published",true);
        List<ResourceModel> list = this.resourceModelService.list(queryWrapper);
        return CollectionUtil.isNotEmpty(list) ;
    }

    public List<JSONObject> getResourceModelJsonObjectList(List<ResourceModel> models) {
        List<JSONObject> jsonList = new ArrayList<>();
        models.forEach(m -> jsonList.add(m.fetchJsonObject()));
        return jsonList;
    }
}
